home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The CICA Windows Explosion!
/
The CICA Windows Explosion! - Disc 2.iso
/
programr
/
cppsum.zip
/
CPPSUM.CPP
next >
Wrap
C/C++ Source or Header
|
1994-06-18
|
9KB
|
262 lines
///////////////////////////////////////////////////////////////////////////
//
// DLL functions to get summary info from OLE 2.0 document files.
//
// Copyright ⌐ 1994 Somar Software, All Rights Reserved
// Send problem reports and comments to 72202.2574@compuserve.com
//
// See cppsum.h for further documentation and change log.
//
#define STRICT
#include <windows.h>
#include <memory.h>
#include <ole2ver.h>
#include <storage.h>
#include <compobj.h>
#include "cppsum.h"
// a temporary function was unreferenced and then removed by optimization
// causing warning 4505
#pragma warning(disable:4505)
///////////////////////////////////////////////////////////////////////////
#define VT_I4 3
#define VT_LPSTR 30
#define VT_FILETIME 64
typedef struct _PROPVALUE {
DWORD vtType;
union {
FILETIME vtTime;
LONG vtLong;
struct {
DWORD cBytes;
char ch[1];
} vtBSTR;
} vtValue;
} PROPVALUE;
typedef PROPVALUE FAR * LPPROPVALUE;
typedef struct _SUMMARYINFO {
DWORD cBytes;
DWORD cProps;
struct {
DWORD propID;
DWORD dwOffset;
} aProps[1];
} SUMMARYINFO;
typedef SUMMARYINFO FAR * LPSUMINFO;
LPPROPVALUE FindProperty(HANDLE hSumInfo, DWORD pid);
///////////////////////////////////////////////////////////////////////////
extern "C" WORD FAR PASCAL __export SumInfoInit()
{
DWORD dwVer = CoBuildVersion();
if (rmm != HIWORD(dwVer)) return 0;
HRESULT hr = CoInitialize(NULL);
SCODE scode = GetScode(hr);
if (scode == S_OK) return 1;
if (scode == S_FALSE) return 2;
return 0;
}
///////////////////////////////////////////////////////////////////////////
extern "C" void FAR PASCAL __export SumInfoUninit(WORD wInitStatus)
{
if (wInitStatus == 1)
CoUninitialize();
}
///////////////////////////////////////////////////////////////////////////
extern "C" HANDLE FAR PASCAL __export SumInfoOpenFile(LPSTR szPath)
{
BOOL bResult = FALSE;
LPSUMINFO lpSumInfo;
DWORD i;
DWORD dwBytesInSection;
HRESULT hr;
ULONG ulBytesRead;
LARGE_INTEGER li;
LPSTREAM pIStream;
LPSTORAGE pIStorage;
HGLOBAL hglb = NULL;
struct {
WORD byteOrder;
WORD wFormat;
WORD osVersion1;
WORD osVersion2;
CLSID classId;
DWORD cSections;
} PropHeader;
struct {
DWORD dwords[4];
DWORD dwOffset;
} FIDAndOffset;
hr = StgOpenStorage(szPath, NULL,
STGM_READ | STGM_SHARE_DENY_NONE | STGM_PRIORITY,
NULL, 0, &pIStorage);
if (FAILED(hr)) return NULL;
hr = pIStorage->OpenStream("\005SummaryInformation", NULL,
STGM_READ | STGM_SHARE_EXCLUSIVE, 0, &pIStream);
if (FAILED(hr)) goto ReleaseStorage;
LISet32(li, 0);
hr = pIStream->Seek(li, STREAM_SEEK_SET, NULL);
if (hr != NOERROR) goto ReleaseStream;
hr = pIStream->Read(&PropHeader, 28, &ulBytesRead);
if (hr != NOERROR || ulBytesRead != 28) goto ReleaseStream;
if (PropHeader.byteOrder != 0xFFFE) goto ReleaseStream;
if (PropHeader.wFormat != 0) goto ReleaseStream;
for (i = 0; i < PropHeader.cSections; i++) {
hr = pIStream->Read(&FIDAndOffset, 20, &ulBytesRead);
if (hr != NOERROR || ulBytesRead != 20) goto ReleaseStream;
if (FIDAndOffset.dwords[0] == 0XF29F85E0 &&
FIDAndOffset.dwords[1] == 0X10684FF9 &&
FIDAndOffset.dwords[2] == 0X000891AB &&
FIDAndOffset.dwords[3] == 0XD9B3272B) break;
}
if (i >= PropHeader.cSections) goto ReleaseStream;
LISet32(li, FIDAndOffset.dwOffset);
hr = pIStream->Seek(li, STREAM_SEEK_SET, NULL);
if (hr != NOERROR) goto ReleaseStream;
hr = pIStream->Read(&dwBytesInSection, 4, &ulBytesRead);
if (hr != NOERROR || ulBytesRead != 4) goto ReleaseStream;
hglb = GlobalAlloc(GPTR, dwBytesInSection);
if (hglb == NULL) goto ReleaseStream;
lpSumInfo = (LPSUMINFO) GlobalLock(hglb);
if (lpSumInfo == NULL) goto Free;
hr = pIStream->Seek(li, STREAM_SEEK_SET, NULL);
if (hr != NOERROR) goto Unlock;
hr = pIStream->Read(lpSumInfo, dwBytesInSection, &ulBytesRead);
if (hr != NOERROR || ulBytesRead > dwBytesInSection) goto Unlock;
// tbd: dwBytesInSection is long by 4 bytes for some Excel 5.0 files, so just
// check that ulBytesRead is <= dwBytesInSection and not that they are equal
GlobalUnlock(hglb);
goto ReleaseStream;
Unlock:
GlobalUnlock(hglb);
Free:
GlobalFree(hglb);
hglb = NULL;
ReleaseStream:
pIStream->Release();
ReleaseStorage:
pIStorage->Release();
return hglb;
}
///////////////////////////////////////////////////////////////////////////
extern "C" void FAR PASCAL __export SumInfoCloseFile(HANDLE hSumInfo)
{
GlobalFree(hSumInfo);
}
///////////////////////////////////////////////////////////////////////////
extern "C" BOOL FAR PASCAL __export SumInfoGetString(HANDLE hSumInfo,
DWORD pid,
LPSTR lpStr,
int cbStr)
{
LPPROPVALUE lpProp = FindProperty(hSumInfo, pid);
if (lpProp == NULL) return FALSE;
if (lpProp->vtType != VT_LPSTR) return FALSE;
int len = (int) lpProp->vtValue.vtBSTR.cBytes;
if (len > cbStr) len = cbStr;
if (len <= 0) {
*(lpStr) = '\0';
}
else {
lstrcpyn(lpStr, lpProp->vtValue.vtBSTR.ch, len);
*(lpStr + len - 1) = '\0'; // len includes terminating null
}
return TRUE;
}
///////////////////////////////////////////////////////////////////////////
extern "C" BOOL FAR PASCAL __export SumInfoGetLong(HANDLE hSumInfo,
DWORD pid,
LPLONG lpLong)
{
LPPROPVALUE lpProp = FindProperty(hSumInfo, pid);
if (lpProp == NULL) return FALSE;
if (lpProp->vtType != VT_I4) return FALSE;
*lpLong = lpProp->vtValue.vtLong;
return TRUE;
}
///////////////////////////////////////////////////////////////////////////
extern "C" BOOL FAR PASCAL __export SumInfoGetTime(HANDLE hSumInfo,
DWORD pid,
LPWORD yr,
LPWORD mon,
LPWORD day,
LPWORD hr,
LPWORD min,
LPWORD sec)
{
struct {
unsigned int day : 5;
unsigned int mon : 4;
unsigned int yr : 7;
} DosDate;
struct {
unsigned int sec2 : 5;
unsigned int min : 6;
unsigned int hr : 5;
} DosTime;
LPPROPVALUE lpProp = FindProperty(hSumInfo, pid);
if (lpProp == NULL) return FALSE;
if (lpProp->vtType != VT_FILETIME) return FALSE;
if (!CoFileTimeToDosDateTime(&lpProp->vtValue.vtTime,
(LPWORD) &DosDate, (LPWORD) &DosTime))
return FALSE;
*yr = (WORD) DosDate.yr + 1980;
*mon = (WORD) DosDate.mon;
*day = (WORD) DosDate.day;
*hr = (WORD) DosTime.hr;
*min = (WORD) DosTime.min;
*sec = (WORD) DosTime.sec2 * 2;
return TRUE;
}
///////////////////////////////////////////////////////////////////////////
LPPROPVALUE FindProperty(HANDLE hSumInfo, DWORD pid)
{
LPPROPVALUE lpProp;
DWORD i;
LPSUMINFO lpSumInfo = (LPSUMINFO) GlobalLock(hSumInfo);
if (lpSumInfo == NULL) return FALSE;
for (i = 0; i < lpSumInfo->cProps; i++) {
if (lpSumInfo->aProps[i].propID == pid) {
lpProp = (LPPROPVALUE) ((LPBYTE) lpSumInfo +
lpSumInfo->aProps[i].dwOffset);
GlobalUnlock(hSumInfo);
return lpProp;
}
}
GlobalUnlock(hSumInfo);
return NULL;
}